﻿using Business.Core.Annotations;
using Business.Data;
using Common;
using DataModel;
using LinqToDB;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ProjectManager.User;
using ProjectManager.User.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectManagerSys
{
    /// <summary>
    /// 调休
    /// </summary>
    public class LeaveMerber : Common.BusinessBase
    {
        [Doc("调休列表", Group = "调休")]
        public virtual async Task<dynamic> leaveList(int page, int limit, string realname, DateTime? startTime, DateTime? endTime)
        {
            try
            {
                using (var con = Data.DB.GetConnection())
                {

                    var list = con.MANAGER_LEAVE.AsQueryable();
                    //权限
                    AuthInfo authinfo = Logins.Authorize();
                    if (authinfo.isadmin != 1)
                    {
                        
                        if (string.IsNullOrEmpty(authinfo.departs)) //个人
                        {
                            list = list.Where(c => c.CREATENAME == authinfo.userid || c.UPDATENAME == authinfo.userid );
                        }
                        else //部门
                        {
                            var arr_depart = authinfo.departid.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                            list = list.Where(c => arr_depart.Contains(c.DEPARTCODE) || c.CREATENAME == authinfo.userid || c.UPDATENAME == authinfo.userid);
                        }
                        //list = list.Where(c => c.CREATENAME == authinfo.userid || c.UPDATENAME == authinfo.userid || c.TASKLEADER.Contains(new_user) || c.TASKMEMBER.Contains(new_user));
                    }

                    list = list.Where(p => p.ACTIVE == 1);
                    if (string.IsNullOrWhiteSpace(realname) == false) //调休人
                        list = list.Where(p => p.REALNAME.Contains(realname));

                    list = startTime.HasValue && endTime.HasValue ? list = list.Where(p => p.STARTTIME >= startTime && p.ENDTIME <= endTime) : list;
                    list = list.OrderByDescending(p => p.STARTTIME);

                    var pageData = list.GetPaging(page, limit);

                    var result = new { code = 0, msg = "", count = pageData.Count, data = pageData.Data };

                    IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
                    timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
                    return JsonConvert.SerializeObject(result, Formatting.Indented, timeFormat);
                }
            }
            catch (Exception ex) { }
            return null;
        }

        [Doc("新增或者修改", Group = "调休")]
        public virtual async Task<dynamic> AddAndUpdateLeave(string arg)
        {
            int flag = 0;
            string message = "";
            try
            {
                AuthInfo authinfo = Logins.Authorize();
                var oModel = JsonConvert.DeserializeObject<MANAGER_LEAVE>(arg);
                
                using (var con = Data.DB.GetConnection())
                {
                    if (!string.IsNullOrEmpty(oModel.ID))
                    {
                        var oLeave = con.MANAGER_LEAVE.Where(c=>c.ID == oModel.ID).FirstOrDefault();
                        oLeave.STARTTIME = oModel.STARTTIME;
                        oLeave.ENDTIME = oModel.ENDTIME;
                        oLeave.LEAVETIMES = oModel.LEAVETIMES;
                        oLeave.DETAIL = oModel.DETAIL;
                        oLeave.UPDATENAME = authinfo.userid;
                        oLeave.UPDATETIME = DateTime.Now;
                        flag = await con.UpdateAsync(oLeave);
                    }
                    else
                    {
                        oModel.ID = Guid.NewGuid().ToString();
                        oModel.ACTIVE = 1;
                        oModel.CREATENAME = authinfo.userid;
                        oModel.REALNAME = authinfo.realname;
                        oModel.DEPARTCODE = authinfo.departid;
                        oModel.CREATETIME = DateTime.Now;
                        oModel.UPDATENAME = authinfo.userid;
                        oModel.UPDATETIME = DateTime.Now;
                        flag = await con.InsertAsync(oModel);
                        dealTask(oModel); //处理需要延迟的任务
                    }
                }
                   
            }
            catch (Exception ex) {
                message = "异常处理，请联系技术人员";
            }

            var obj = new { flag = flag , message = message };
            return obj;
        }

        [Doc("逻辑删除", Group = "调休")]
        public virtual async Task<dynamic> DeleteLeave(string delIds)
        {
            using (var con = Data.DB.GetConnection())
            {
                var flag = 0;
                if (!String.IsNullOrEmpty(delIds))
                {
                    var idArray = delIds.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    if (idArray.Length > 0)
                    {
                        foreach (var item in idArray)
                        {
                            var oModel = con.MANAGER_LEAVE.Where(c => c.ID == item).FirstOrDefault();
                            if (oModel != null)
                            {
                                oModel.ACTIVE = 0;
                                flag += await con.UpdateAsync(oModel);
                            }
                        }
                    }
                }

                return (flag);
            }
        }

        [Doc("计算调休时长", Group = "调休")]
        public virtual async Task<dynamic> CalculateLeave(string startTime,string endTime)
        {
            double times = 0;
            if (!string.IsNullOrEmpty(startTime) && !string.IsNullOrEmpty(endTime))
            {
                times = new TaskMerber().CalculationWorkHour(Convert.ToDateTime(startTime),Convert.ToDateTime(endTime));
            }
            return JsonConvert.SerializeObject(Math.Round(times,2));
        }

        /// <summary>
        /// 处理包含在调休时间里的任务
        /// </summary>
        /// <param name="oLeave"></param>
        public void dealTask(MANAGER_LEAVE oLeave)
        {
            //开始时间含在其他任务的时间段里并且是已完成的任务和已验收的任务
            string where = "";
            AuthInfo authinfo = Logins.Authorize();
            where += string.Format(" (CREATENAME='{0}' or UPDATENAME='{0}') ",authinfo.userid);
            StringBuilder sql = new StringBuilder();
            sql.Append("select * from manager_task where id not in(select ID from manager_task ");
            sql.AppendFormat(" where to_date('{0}', 'yyyy-mm-dd hh24:mi:ss') >= TASKENDTIME", oLeave.STARTTIME);
            sql.AppendFormat(" or to_date('{0}', 'yyyy-mm-dd hh24:mi:ss') <= TASKSTARTTIME)", oLeave.ENDTIME);
            sql.AppendFormat(" and active = 1 and  TASKSTARTTIME is not null and TASKENDTIME is not null and {0} ", where);
            using (var con = Data.DB.GetConnection())
            {
                var list = con.Execute<MANAGER_TASK>(sql.ToString()).ToList();
                if(list.Count > 0)
                {
                    foreach (var item in list)
                    {
                        DateTime minstartTime = oLeave.STARTTIME > item.TASKSTARTTIME ? (DateTime)item.TASKSTARTTIME : (DateTime)oLeave.STARTTIME;
                        DateTime maxEndTime = item.TASKENDTIME > oLeave.ENDTIME ? (DateTime)item.TASKENDTIME : (DateTime)oLeave.ENDTIME;

                        //获取最大结束时间加上时差天数的的list
                        int days = (maxEndTime - minstartTime).Days + 1;
                        var timeList = DateOperation.GetWorkList(minstartTime, (days * 2 + 2));
                        //获取最大结束时间到结束时间加上差值的补班
                        var testList = new TimeValidate().GetWeekOrWorkList(maxEndTime, maxEndTime.AddDays(days), 2);
                        var timelist2 = testList.Select(c => c.HOLIDAY).ToList();
                        //总
                        var totalTime = timeList.Union(timelist2).ToList<DateTime?>().OrderBy(c => c.Value).ToArray();
                        ////获取最终结束时间的小时分钟
                        int index = 0;
                        string hourAndMinuter = new CalculateMatrixTime().LastTime(minstartTime, (int)(oLeave.LEAVETIMES * 60), (int)(item.CALTOTAL * 60), out index);
                        item.TASKENDTIME = Convert.ToDateTime(Convert.ToDateTime(totalTime[index - 1]).ToString("yyyy-MM-dd") + " " + hourAndMinuter);
                        item.CALTOTAL = (decimal)new TaskMerber().CalculationWorkHour(item.TASKSTARTTIME, item.TASKENDTIME);

                        con.UpdateAsync(item);
                    }
                }
            }
                
        }
    }
}
